/**
  ******************************************************************************
  * @file    by9301.c
  * @author  ashuai0110
  * @version V2.3
  * @date    2024-07-01
  * @brief   BY9301语音播报模块驱动
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  * Change Logs:
  * Date          Author        Notes
  * 2024-03-31    ashuai0110    完成基本内容
  *
  ******************************************************************************
  */

/* 包含头文件-----------------------------------------------------------------*/
#include "by9301.h"

/**
 * @addtogroup devices
 * @{
 */

/**
 * @defgroup by9301 by9301
 * @{
 */

/* 私有宏定义-----------------------------------------------------------------*/

/* 私有类型定义---------------------------------------------------------------*/

/* 私有变量-------------------------------------------------------------------*/
/**
 * @defgroup by9301_local_variables by9301 local variables
 * @{
 */

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 私有函数原型---------------------------------------------------------------*/
/**
 * @defgroup by9301_local_functions by9301 local functions
 * @{
 */

/**
 * @}
 */

/**
 * @defgroup by9301_global_functions by9301 global functions
 * @{
 */

/**
  * @brief  BY9301初始化
  *
  * @param  _by9301 : BY9301管理实例
  *
  * @param  readFn  : IO端口模式设置函数
  *
  * @param  writeFn : IO端口读写函数
  *
  * @retval None
  */
void by9301_init(by9301_t *_by9301, uint8_t (* ioBusyReadFn)(void), module_read_write_fn_t readFn, module_read_write_fn_t writeFn)
{
    ASSERT_PARAM(IS_VALID_POINT(_by9301));
    ASSERT_PARAM(IS_VALID_POINT(readFn));
    ASSERT_PARAM(IS_VALID_POINT(writeFn));
    
    memset((void *)_by9301, 0, sizeof(by9301_t));
    _by9301->ioBusyReadFn = ioBusyReadFn;
    _by9301->readFn = readFn;
    _by9301->writeFn = writeFn;
}

/**
  * @brief  BY9301指定序号播放
  *
  * @param  _by9301      : BY9301管理实例
  *
  * @param  num          : 播放MP3的序号1~255
  *
  * @param  mode         : 播放模式
  *   @arg  BY9301_BUSY  : 忙时不播放(依据busy端口判断是否播放)
  *   @arg  BY9301_BREAK : 忙时打断播放(不关心busy端口状态,直接发送播放命令)
  *
  * @retval None
  */
void by9301_play_with_num(by9301_t *_by9301, uint8_t num, uint8_t mode)
{
    uint8_t data[7];
    
    ASSERT_PARAM(IS_VALID_POINT(_by9301));
    
    if(BY9301_BUSY == mode)
    {
        ASSERT_PARAM(IS_VALID_POINT(_by9301->ioBusyReadFn));
        if(_by9301->ioBusyReadFn())
        {
            return ;
        }
    }
    
    data[0] = 0x7E;
    data[1] = 0x05;
    data[2] = 0x41;
    data[3] = 0x00;
    data[4] = num;
    data[5] = data[1]^data[2]^data[3]^data[4];
    data[6] = 0xEF;
    _by9301->writeFn((void *)data, 7);
}

/**
  * @brief  BY9301设置音量
  *
  * @param  _by9301 : BY9301管理实例
  *
  * @param  volume  : 音量0~30
  *
  * @retval None
  */
void by9301_set_volume(by9301_t *_by9301, uint8_t volume)
{
    uint8_t data[6];
    
    ASSERT_PARAM(IS_VALID_POINT(_by9301));
    
    if(volume > 30) volume = 30;
    data[0] = 0x7E;
    data[1] = 0x04;
    data[2] = 0x31;
    data[3] = volume;
    data[4] = data[1]^data[2]^data[3];
    data[5] = 0xEF;
    _by9301->writeFn((void *)data, 6);
}

/**
  * @brief  BY9301播放暂停
  *
  * @param  _by9301      : BY9301管理实例
  *
  * @param  playPause    : 播放暂停标志
  *    @arg BY9301_PAUSE : 暂停
  *    @arg BY9301_PLAY  : 播放
  *
  * @retval None
  */
void by9301_play_pause(by9301_t *_by9301, uint8_t playPause)
{
    uint8_t data[5];
    
    ASSERT_PARAM(IS_VALID_POINT(_by9301));
    
    data[0] = 0x7E;
    data[1] = 0x03;
    data[2] = playPause == BY9301_PLAY ? 0x1 : 0x2;
    data[3] = data[1]^data[2];
    data[4] = 0xEF;
    _by9301->writeFn((void *)data, 5);
}

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

